#ifndef GPIOINPUT_H
#define GPIOINPUT_H

#include <QObject>
#include <QSocketNotifier>
#include <QTimer>
#include <QMap>

#ifdef Q_OS_LINUX
#include <poll.h>
#endif

namespace ns_yht
{

    /**
     * @brief GPIO按键输入处理类
     *
     * 该类用于处理嵌入式系统上的GPIO按键输入。
     *
     * 使用示例：
     * @code
     * GpioInput *gpioInput = new GpioInput(this);
     * // 添加GPIO按键，参数为GPIO编号和按键码
     * gpioInput->addGpioButton(18, KEY_POWER);  // GPIO18作为电源键
     * gpioInput->addGpioButton(23, KEY_VOLUMEUP);  // GPIO23作为音量加键
     *
     * // 连接按键信号
     * connect(gpioInput, &GpioInput::keyPressed, [](int keycode) {
     *     switch(keycode) {
     *     case KEY_POWER:
     *         // 处理电源键
     *         break;
     *     case KEY_VOLUMEUP:
     *         // 处理音量加键
     *         break;
     *     }
     * });
     * @endcode
     */
    class GpioInput : public QObject
    {
        Q_OBJECT

    public:
        explicit GpioInput(QObject *parent = nullptr);
        ~GpioInput();

        /**
         * @brief 添加GPIO按键
         * @param gpioNumber GPIO编号
         * @param keyCode 对应的按键码
         * @return 是否添加成功
         */
        bool addGpioButton(int gpioNumber, int keyCode);

    signals:
        /**
         * @brief 按键按下信号
         * @param keycode 按键码
         */
        void keyPressed(int keycode);

        /**
         * @brief 按键释放信号
         * @param keycode 按键码
         */
        void keyReleased(int keycode);

    private slots:
        void handleGpioEvent();

    private:
        bool exportGpio(int gpioNumber);
        bool configureGpio(int gpioNumber, const QString &direction);
        bool configureGpioEdge(int gpioNumber, const QString &edge);
        int openGpioValueFile(int gpioNumber);

        struct GpioButton
        {
            int gpioNumber;
            int keyCode;
            int fd;
            QSocketNotifier *notifier;
            int lastValue; // 上次读取的值，用于去抖动和检测变化
        };

        QList<GpioButton> m_gpioButtons;
        // QTimer *m_pollingTimer;  // 备用轮询定时器（如果poll方式不可用）
    };

} // namespace ns_yht

#endif // GPIOINPUT_H